﻿using UnityEngine;

public abstract class UIComponent {
	// === Public =====================================================================================================
	// --- Position ---
	public Vector2 GetLocation() { return new Vector2(_x, _y); }
	public void SetLocation(Vector2 location) { SetLocation((int)location.x, (int)location.y); }
	public void SetLocation(int x, int y) { Move(x, y); }

	public Vector2 GetSize() { return new Vector2(_width, _height); }
	public void SetSize(Vector2 size) { SetSize((int)size.x, (int)size.y); }
	public void SetSize(int width, int height) { Resize(width, height); }

	public Rect GetRect() { return new Rect(_x, _y, _width, _height); }

	// --- Background ---
	public Texture2D GetBackgroundNormal() { return _backgroundNormal ?? Managers.UI.GetBackgroundNormal(_name); }

	public void SetBackgroundNormal(Texture2D background) {
		_backgroundNormal = background;
		UpdateStyle();
	}
	public Texture2D GetBackgroundHover() { return _backgroundHover ?? Managers.UI.GetBackgroundHover(_name); }

	public void SetBackgroundHover(Texture2D background) {
		_backgroundHover = background;
		UpdateStyle();
	}
	public Texture2D GetBackgroundActive() { return _backgroundActive ?? Managers.UI.GetBackgroundActive(_name); }

	public void SetBackgroundActive(Texture2D background) {
		_backgroundActive = background;
		UpdateStyle();
	}

	public Vector4 GetBackgroundBorder() {
		return !_backgroundBorder.Equals(new Vector4(-1, -1, -1, -1)) ? _backgroundBorder : Managers.UI.GetBackgroundBorder(_name);
	}

	public void SetBackgroundBorder(int left, int right, int top, int bottom) { SetBackgroundBorder(new Vector4(left, right, top, bottom)); }

	public void SetBackgroundBorder(Vector4 backgroundBorder) {
		_backgroundBorder = backgroundBorder;
		UpdateStyle();
	}

	// --- Font ---
	public Font GetFont() { return _font; }
	public bool IsFontSet() { return _font != null; }

	public void SetFont(Font font) {
		_font = font;
		UpdateStyle();
	}

	// --- Cursor ---
	public Cursor GetCursor() { return _cursor; }
	public bool IsCursorSet() { return _cursor != null; }
	public void SetCursor(Cursor cursor) { _cursor = cursor; }

	// --- Ignore ---
	public bool GetIgnoreRepaint() { return _ignoreRepaint; }
	public void SetIgnoreRepaint(bool ignoreRepaint) { _ignoreRepaint = ignoreRepaint; }

	// --- Visible ---
	public bool IsVisible() { return _visible; }
	public void SetVisible(bool visible) { _visible = visible; }

	// --- Enabled ---
	public bool IsEnabled() { return _enabled; }

	public void SetEnabled(bool enabled) {
		_enabled = enabled;
		UpdateStyle();
	}

	// --- Name ---
	public string GetName() { return _name; }
	protected void SetName(string name) { _name = name; }

	// --- Text ---
	public string GetText() { return _text ?? string.Empty; }
	public void SetText(string text) { _text = text; }

	public Color GetTextColor() { return _textColor; }

	public void SetTextColor(Color textColor) {
		_textColor = textColor;
		UpdateStyle();
	}

	// --- Style ---
	public GUIStyle GetStyle() { return _style; }

	// === Protected ==================================================================================================
	protected void UpdateStyle() {
		if (IsEnabled()) {
			_style.normal.background = GetBackgroundNormal();
			_style.hover.background = GetBackgroundHover();
			_style.active.background = GetBackgroundActive();
			_style.normal.textColor = _style.hover.textColor = _style.active.textColor = GetTextColor();
		} else {
			_style.normal.background = GetBackgroundNormal();
			_style.hover.background = GetBackgroundNormal();
			_style.active.background = GetBackgroundNormal();
			_style.normal.textColor = _style.hover.textColor = _style.active.textColor = Color.gray;
		}

		var border = GetBackgroundBorder();
		_style.border.left = (int)border.x;
		_style.border.right = (int)border.y;
		_style.border.top = (int)border.z;
		_style.border.bottom = (int)border.w;
		_style.font = GetFont();
		_style.alignment = TextAnchor.MiddleCenter;
	}

	// === Private ====================================================================================================
	private int _x;						//The x position of the component in the parent's coordinate system.
	private int _y;						//The y position of the component in the parent's coordinate system.
	private int _width;					//The width of the component.
	private int _height;				//The height of the component.
	private Texture2D _backgroundNormal;//The backgroundNormal texture for this component. BackgroundNormal can be null.
	private Texture2D _backgroundHover;	//The backgroundHover texture for this component. BackgroundHover can be null.
	private Texture2D _backgroundActive;//The backgroundActive texture for this component. BackgroundActive can be null.
	private Vector4 _backgroundBorder = new Vector4(-1, -1, -1, -1);	//The border of the background for this component.
	private Font _font;					//The font used by this component. The font can be null.
	private Cursor _cursor;				//The cursor displayed when pointer is over this component. This value can be null.
	private bool _ignoreRepaint;		//True when the object should ignore all repaint events.
	private bool _visible = true;		//True when the object is visible. An object that is not visible is not drawn on the screen.
	private bool _enabled = true;		//True when the object is enabled. An object that is not enabled does not interact with the user.
	private string _name;				//A component's name. This field can be null.
	private string _text;				//The text for this compontent. Text can be null.
	private Color _textColor = Color.white;
	private readonly GUIStyle _style = new GUIStyle();

	private void Move(int x, int y) {
		_x = x;
		_y = y;
	}

	private void Resize(int width, int height) {
		_width = width;
		_height = height;
	}
}
